/**
 * ...
 * @author Franco Ponticelli
 */

package uform.ui.comp;
import uform.ui.comp.INamedComponent;
import uform.property.Property;
import uform.ui.comp.Trigger;
import uform.ui.comp.Container;
import uform.ui.comp.RepeaterItem;
import uform.property.IProperty;
import uform.property.Property;
import hxevents.Dispatcher;
import uform.ui.comp.Component;
import uform.property.IMonadicProperty;
import uform.property.MonadicProperty;

class Repeater extends Container, implements INamedComponent
{
	public var name(default, setName) : String;
	public var template(default, null) : Void -> Component;
	public var addTrigger(default, null) : Trigger;
	public var removeTrigger(default, null) : Trigger;
	public var items(default, null) : ReadStack;
	public var actions(default, null) : Stack;   
	public var min(default, null) : IProperty<Int>;
	public var max(default, null) : IProperty<Int>;
	
	var _items : Stack;
	public function new(name : String, template : Void -> Component, min = 0, max : Null<Int>= null)
	{
		super();
		this.name = name;   
		min = null == min ? 0 : min;
		this.min = new Property(min);  
		this.max = new Property(max);  
		this.items = _items = new Stack();
		this.actions = new Stack();
		_parentFor(items);
		_parentFor(actions);
		this.template = template;
		addTrigger = new Trigger("add", "add", _create);
		removeTrigger = new Trigger("remove", "remove", delete);
		removeTrigger.enabled.set(false);
		actions.add(addTrigger);
		actions.add(removeTrigger); 
		createMany(min);
		this.min.onChange.add(_min);
		this.max.onChange.add(_max);
	}

	override function _id()
	{
		if (null == name || "" == name) 
			return "R";
		else
			return name;
	}
	
	function _min()
	{
		while(this.items.length < min.get()) 
			create();
	}  
	
	function _max()
	{
		if(max.isNull())
			return;
		while(this.items.length > max.get())
			delete();
	}
	
	function _create()
	{
		create();
	}
	
	public function create()
	{
		if (items.length == max.get())
			return null;
		var item = new RepeaterItem(template());
		_items.addItem(item);
		if (items.length > min.get())
			removeTrigger.enabled.set(true);
		if (items.length == max.get())
			addTrigger.enabled.set(false);
		return item;
	}
	
	public function createMany(number : Int)
	{
		for (i in 0...number)
			create();
	}
	
	public function delete()
	{
		if (items.length == min.get())
			return;
		items.remove(items.last());
		if (items.length == min.get())
			removeTrigger.enabled.set(false);
		if (items.length < max.get())
			addTrigger.enabled.set(true);
	}
    
	override public function path()
	{
		var parts = [];
		if (!parent.isNull())
			parts.push(parent.get().path());
		if ("" != name && null != name)
			parts.push(name);
		return parts.join(".");
	}
	
	public function clear()
	{
		_items.clear();
	}
	
	function setName(name : String)
	{
		return this.name = name;
	}
	
	override function componentByPath(path : String) : INamedComponent {
		var ctrl = actions.componentByPath(path);
		if (null != ctrl)
			return ctrl;
		return items.componentByPath(path);
	}
	
	override function componentByName(name : String) : INamedComponent {
		var ctrl = actions.componentByName(name);
		if (null != ctrl)
			return ctrl;
		return items.componentByName(name);
	}
}